package lesson06.timer;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 自定义实现定时器
 *
 * @author wileda
 * @date 2023/01/13  14:19
 */
public class MyTimer {
    //使用优先级队列来保存任务
    private BlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();
    //定义一个锁
    Object locker = new Object();
    //定义一个添加任务的方法
    public void schedule(Runnable runnable,long time) throws InterruptedException {
        MyTask myTask = new MyTask(runnable,time);
        queue.put(myTask);
        synchronized (locker){
            locker.notifyAll();
        }
    }

    public MyTimer() throws InterruptedException {
            Thread thread = new Thread(() -> {
                while (true) {
                try {
                        MyTask result = queue.take();
                    if (System.currentTimeMillis() >= result.getTime()) {
                        result.getRunnable().run();
                    } else {
                        queue.put(result);
                        long waitTime = result.getTime() - System.currentTimeMillis();
                        synchronized (locker){
                            locker.wait(waitTime);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            });
            thread.start();

            //创建一个后台线程专门来唤醒
        Thread daemonThread = new Thread(() ->{
            while (true){
                synchronized (locker){
                    locker.notifyAll();
                }
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        daemonThread.setDaemon(true);
        daemonThread.start();
    }
}
//描述定时器的任务
class MyTask implements Comparable<MyTask>{
    //描述定时器任务
    private Runnable runnable;
    //记录定时器的时间
    private long time;

    public Runnable getRunnable() {
        return runnable;
    }

    public long getTime() {
        return time;
    }

    public MyTask(Runnable runnable, long time) {
        if(time < 0){
            throw  new RuntimeException("延迟时间不能小于0");
        }
        this.runnable = runnable;
        //time记录的是任务的具体执行时间  等待时间加上系统当前时间
        this.time = time + System.currentTimeMillis();
    }

    @Override
    public int compareTo(MyTask o) {
        if(this.time == o.getTime()){
            return 0;
        }
        if(this.time > o.getTime()){
            return 1;
        }else {
            return -1;
        }
//        return (int) (this.time - o.getTime());
    }
}